{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "c46f2b24-657f-46ab-b025-8c48ae1e9a04",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2023-04-13 17:45:33.764284: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA\n",
      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
      "2023-04-13 17:45:34.726982: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory\n",
      "2023-04-13 17:45:34.727114: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory\n",
      "2023-04-13 17:45:34.727126: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
      "2023-04-13 17:45:36.092032687 [W:onnxruntime:Default, onnxruntime_pybind_state.cc:540 CreateExecutionProviderInstance] Failed to create TensorrtExecutionProvider. Please reference https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html#requirements to ensure all dependencies are met.\n",
      "2023-04-13 17:45:36.117269587 [W:onnxruntime:Default, onnxruntime_pybind_state.cc:540 CreateExecutionProviderInstance] Failed to create TensorrtExecutionProvider. Please reference https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html#requirements to ensure all dependencies are met.\n",
      "2023-04-13 17:45:36.183566587 [W:onnxruntime:Default, onnxruntime_pybind_state.cc:540 CreateExecutionProviderInstance] Failed to create TensorrtExecutionProvider. Please reference https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html#requirements to ensure all dependencies are met.\n",
      "[WARNING 2023-04-13 17:45:36,259 _assert_and_prepare_model_files:124] can not find model file /root/.cnstd/1.2/ppocr/en_PP-OCRv3_det_infer.onnx \n",
      "2171KB [00:06, 356.45KB/s]                                                                                                                                              \n",
      "2023-04-13 17:45:43.872053917 [W:onnxruntime:Default, onnxruntime_pybind_state.cc:540 CreateExecutionProviderInstance] Failed to create TensorrtExecutionProvider. Please reference https://onnxruntime.ai/docs/execution-providers/TensorRT-ExecutionProvider.html#requirements to ensure all dependencies are met.\n",
      "weights.pth: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 97.4M/97.4M [00:14<00:00, 7.01Mb/s]\n",
      "image_resizer.pth: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████| 18.5M/18.5M [00:04<00:00, 3.97Mb/s]\n",
      "[WARNING 2023-04-13 17:46:07,224 _assert_and_prepare_clf_model:170] no .ckpt file is found in /root/.pix2text/clf \n",
      "8228KB [00:01, 4325.77KB/s]                                                                                                                                             \n",
      "[WARNING 2023-04-13 17:46:10,840 _showwarnmsg:109] /home/kewei/miniconda3/lib/python3.9/site-packages/torch/functional.py:568: UserWarning: torch.meshgrid: in an upcoming release, it will be required to pass the indexing argument. (Triggered internally at  ../aten/src/ATen/native/TensorShape.cpp:2228.)\n",
      "  return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]\n",
      " \n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING: --img-size 671 must be multiple of max stride 32, updating to 672\n",
      "WARNING: --img-size 600 must be multiple of max stride 32, updating to 608\n",
      "[{'type': 'text', 'text': 'DES 分组密码是一个拥有16轮的 Feistel 网络，且分块长度为64比特，密钥长度为56 比', 'position': array([[         56,          17],\n",
      "       [        688,          17],\n",
      "       [        688,          34],\n",
      "       [         56,          34]], dtype=float32)}, {'type': 'text', 'text': '特。回顾在Feistel 网络中，每一轮中使用的内部f函数一次只操作半个分块。因此，DES 轮', 'position': array([[         21,          40],\n",
      "       [        688,          40],\n",
      "       [        688,          59],\n",
      "       [         21,          59]], dtype=float32)}, {'type': 'text', 'text': '函数的输入/输出长度就是32比特。在DES的16轮中每轮所用到的轮函数都是由同一个变形', 'position': array([[         23,          63],\n",
      "       [        688,          63],\n",
      "       [        688,          82],\n",
      "       [         23,          82]], dtype=float32)}, {'type': 'text-embed', 'text': '函数f:= $\\\\overline{{f}}$ 推导而来的。DES 的密码编排被用来从56 比特的主密钥k中获得每一轮的 48 比特', 'position': array([[         22,          86],\n",
      "       [        686,          86],\n",
      "       [        686,         105],\n",
      "       [         22,         105]], dtype=float32)}, {'type': 'text-embed', 'text': '的子密钥k;。如在前一节所讨论的，第个轮函数/,就被定义为f(R）二 ${\\\\tilde{f}}(k_{i},$ R。正如从DES', 'position': array([[         19,         109],\n",
      "       [        691,         109],\n",
      "       [        691,         139],\n",
      "       [         19,         139]], dtype=float32)}, {'type': 'text', 'text': '使用 Feistel 结构这一事实所期望的，轮函数是不可逆的', 'position': array([[         24,         143],\n",
      "       [        421,         143],\n",
      "       [        421,         158],\n",
      "       [         24,         158]], dtype=float32)}, {'type': 'text', 'text': 'DES的密钥编排相对比较简单，每一个子密钥k;都是由主密钥估算出的 48 比特的子集。', 'position': array([[         55,         166],\n",
      "       [        677,         166],\n",
      "       [        677,         184],\n",
      "       [         55,         184]], dtype=float32)}, {'type': 'text', 'text': '这里不精确地描述密钥编排。主密钥的 56 比特被分成两部分，即“左半部分”和“右半部', 'position': array([[         22,         188],\n",
      "       [        686,         188],\n",
      "       [        686,         208],\n",
      "       [         22,         208]], dtype=float32)}, {'type': 'text', 'text': '分”，其中每一部分含有 28比特（事实上，这种分离发生在密钥的初始置换之后，但是这里', 'position': array([[         23,         212],\n",
      "       [        685,         212],\n",
      "       [        685,         230],\n",
      "       [         23,         230]], dtype=float32)}, {'type': 'text', 'text': '的描述中忽略这些)。在每一轮中，子密钥最左边的 24比特被当作是主密钥左半部分 28 比特', 'position': array([[         23,         235],\n",
      "       [        685,         235],\n",
      "       [        685,         254],\n",
      "       [         23,         254]], dtype=float32)}, {'type': 'text', 'text': '的某个子集，而子密钥最右边的 24 比特被当作主密钥右半部分 28比特的某个子集。整个密', 'position': array([[         23,         259],\n",
      "       [        685,         259],\n",
      "       [        685,         277],\n",
      "       [         23,         277]], dtype=float32)}, {'type': 'text', 'text': '钥编排（包括比特被分为左半部分和右半部分，以及哪些比特被用来形成子密钥:;）都是确', 'position': array([[         23,         282],\n",
      "       [        685,         282],\n",
      "       [        685,         301],\n",
      "       [         23,         301]], dtype=float32)}, {'type': 'text', 'text': '定和公开的，唯一机密的是主密钥本身。', 'position': array([[         23,         307],\n",
      "       [        306,         307],\n",
      "       [        306,         322],\n",
      "       [         23,         322]], dtype=float32)}, {'type': 'text', 'text': 'DES 变形函数了。前面曾经提到：变形函数了和第i个子密钥k:;共同决定了第轮函数f,', 'position': array([[         53,         328],\n",
      "       [        677,         328],\n",
      "       [        677,         350],\n",
      "       [         53,         350]], dtype=float32)}, {'type': 'text', 'text': 'DES 中的变形函数是根据之前分析的范例构造出来的：它（本质上）只是一个单轮代替置换', 'position': array([[         21,         352],\n",
      "       [        686,         352],\n",
      "       [        686,         372],\n",
      "       [         21,         372]], dtype=float32)}, {'type': 'text-embed', 'text': '网络。更详细地说，使用 $K_{i}\\\\in\\\\{0,1\\\\}$ 48和R∈ {0, 1}32计算了(k:;, R)，方法如下；首先R被扩展', 'position': array([[         22,         374],\n",
      "       [        686,         374],\n",
      "       [        686,         396],\n",
      "       [         22,         396]], dtype=float32)}, {'type': 'text-embed', 'text': '成个 48比特的值R’。这是通过复制R一半的比特来完成的；用 $R^{\\\\prime}:=E(R)$ 来表示，这里瓦', 'position': array([[         23,         397],\n",
      "       [        687,         397],\n",
      "       [        687,         418],\n",
      "       [         23,         418]], dtype=float32)}, {'type': 'text', 'text': '代表扩展函数。然后，完全按照之前讨论的代替置换网络中的方法进行计算；展开值R’和k', 'position': array([[         21,         422],\n",
      "       [        686,         422],\n",
      "       [        686,         444],\n",
      "       [         21,         444]], dtype=float32)}, {'type': 'text', 'text': '进行异或运算，结果被分解为8块，每一块长度为6比特。每一个分块都经过（不同的）S', 'position': array([[         21,         445],\n",
      "       [        688,         445],\n",
      "       [        688,         467],\n",
      "       [         21,         467]], dtype=float32)}, {'type': 'text', 'text': '盒，S盒的输入为6比特且输出为4比特；把8个S盒的输出连接起来就得到了一个32比特', 'position': array([[         22,         470],\n",
      "       [        684,         470],\n",
      "       [        684,         488],\n",
      "       [         22,         488]], dtype=float32)}, {'type': 'text-embed', 'text': '的结果。最后一步，对这个结果使用混合置换，从而获得 $\\\\hat{f}$ 的最终输出。构造过程图如图 5.4', 'position': array([[         22,         493],\n",
      "       [        686,         493],\n",
      "       [        686,         512],\n",
      "       [         22,         512]], dtype=float32)}, {'type': 'text', 'text': '所示。', 'position': array([[         22,         516],\n",
      "       [         62,         516],\n",
      "       [         62,         534],\n",
      "       [         22,         534]], dtype=float32)}, {'type': 'text', 'text': '与最初讨论的代替置换网络相比，这里的一个不同是上面所提到的S盒是不可逆的；实', 'position': array([[         53,         539],\n",
      "       [        686,         539],\n",
      "       [        686,         561],\n",
      "       [         53,         561]], dtype=float32)}, {'type': 'text', 'text': '际上，它们不可能是可逆的，因为它们的输入比输出长。更多关于S盒的结构细节在后面', 'position': array([[         21,         563],\n",
      "       [        685,         563],\n",
      "       [        685,         584],\n",
      "       [         21,         584]], dtype=float32)}, {'type': 'text', 'text': '给出。', 'position': array([[         22,         588],\n",
      "       [         61,         588],\n",
      "       [         61,         603],\n",
      "       [         22,         603]], dtype=float32)}, {'type': 'text', 'text': '再次强调上面所描述的一切（包括S盒本身以及混合置换）都是公开的。唯一保密的是', 'position': array([[         54,         610],\n",
      "       [        684,         610],\n",
      "       [        684,         631],\n",
      "       [         54,         631]], dtype=float32)}, {'type': 'text', 'text': '用来获得所有子密钥的主密钥。', 'position': array([[         22,         634],\n",
      "       [        239,         634],\n",
      "       [        239,         649],\n",
      "       [         22,         649]], dtype=float32)}, {'type': 'text', 'text': 'S盒。构成广“核心”的8个S盒是 DES 构造方法中重要的组成部分，而且是精心设计', 'position': array([[         52,         654],\n",
      "       [        683,         654],\n",
      "       [        683,         676],\n",
      "       [         52,         676]], dtype=float32)}, {'type': 'text', 'text': '的（据报道是在国家安全局的帮助下)。对 DES 的研究表明；如果对S盒引入一些小变化', 'position': array([[         22,         678],\n",
      "       [        675,         678],\n",
      "       [        675,         699],\n",
      "       [         22,         699]], dtype=float32)}, {'type': 'text', 'text': '或者S盒是随机选择的，DES 将会更容易受到攻击。这应该作为对所有想设计分组密码的人', 'position': array([[         22,         701],\n",
      "       [        683,         701],\n",
      "       [        683,         722],\n",
      "       [         22,         722]], dtype=float32)}, {'type': 'text', 'text': '一个警告：看上去随意的选择实际上完全不是随意的，如果做得不正确，则会使整个结构不', 'position': array([[         22,         725],\n",
      "       [        684,         725],\n",
      "       [        684,         744],\n",
      "       [         22,         744]], dtype=float32)}, {'type': 'text', 'text': '安全。', 'position': array([[         22,         749],\n",
      "       [         59,         749],\n",
      "       [         59,         765],\n",
      "       [         22,         765]], dtype=float32)}]\n"
     ]
    }
   ],
   "source": [
    "from pix2text import Pix2Text\n",
    "\n",
    "img_fp = './pic/in1.png'\n",
    "p2t = Pix2Text(analyzer_config=dict(model_name='mfd'))\n",
    "outs = p2t(img_fp, resized_shape=600)  # 也可以使用 `p2t.recognize(img_fp)` 获得相同的结果\n",
    "print(outs)\n",
    "# 如果只需要识别出的文字和Latex表示，可以使用下面行的代码合并所有结果\n",
    "only_text = '\\n'.join([out['text'] for out in outs])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "e97374f8-a545-480a-9cd4-745c586c10f5",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "only_text='DES 分组密码是一个拥有16轮的 Feistel 网络，且分块长度为64比特，密钥长度为56 比\\n特。回顾在Feistel 网络中，每一轮中使用的内部f函数一次只操作半个分块。因此，DES 轮\\n函数的输入/输出长度就是32比特。在DES的16轮中每轮所用到的轮函数都是由同一个变形\\n函数f:= $\\\\overline{{f}}$ 推导而来的。DES 的密码编排被用来从56 比特的主密钥k中获得每一轮的 48 比特\\n的子密钥k;。如在前一节所讨论的，第个轮函数/,就被定义为f(R）二 ${\\\\tilde{f}}(k_{i},$ R。正如从DES\\n使用 Feistel 结构这一事实所期望的，轮函数是不可逆的\\nDES的密钥编排相对比较简单，每一个子密钥k;都是由主密钥估算出的 48 比特的子集。\\n这里不精确地描述密钥编排。主密钥的 56 比特被分成两部分，即“左半部分”和“右半部\\n分”，其中每一部分含有 28比特（事实上，这种分离发生在密钥的初始置换之后，但是这里\\n的描述中忽略这些)。在每一轮中，子密钥最左边的 24比特被当作是主密钥左半部分 28 比特\\n的某个子集，而子密钥最右边的 24 比特被当作主密钥右半部分 28比特的某个子集。整个密\\n钥编排（包括比特被分为左半部分和右半部分，以及哪些比特被用来形成子密钥:;）都是确\\n定和公开的，唯一机密的是主密钥本身。\\nDES 变形函数了。前面曾经提到：变形函数了和第i个子密钥k:;共同决定了第轮函数f,\\nDES 中的变形函数是根据之前分析的范例构造出来的：它（本质上）只是一个单轮代替置换\\n网络。更详细地说，使用 $K_{i}\\\\in\\\\{0,1\\\\}$ 48和R∈ {0, 1}32计算了(k:;, R)，方法如下；首先R被扩展\\n成个 48比特的值R’。这是通过复制R一半的比特来完成的；用 $R^{\\\\prime}:=E(R)$ 来表示，这里瓦\\n代表扩展函数。然后，完全按照之前讨论的代替置换网络中的方法进行计算；展开值R’和k\\n进行异或运算，结果被分解为8块，每一块长度为6比特。每一个分块都经过（不同的）S\\n盒，S盒的输入为6比特且输出为4比特；把8个S盒的输出连接起来就得到了一个32比特\\n的结果。最后一步，对这个结果使用混合置换，从而获得 $\\\\hat{f}$ 的最终输出。构造过程图如图 5.4\\n所示。\\n与最初讨论的代替置换网络相比，这里的一个不同是上面所提到的S盒是不可逆的；实\\n际上，它们不可能是可逆的，因为它们的输入比输出长。更多关于S盒的结构细节在后面\\n给出。\\n再次强调上面所描述的一切（包括S盒本身以及混合置换）都是公开的。唯一保密的是\\n用来获得所有子密钥的主密钥。\\nS盒。构成广“核心”的8个S盒是 DES 构造方法中重要的组成部分，而且是精心设计\\n的（据报道是在国家安全局的帮助下)。对 DES 的研究表明；如果对S盒引入一些小变化\\n或者S盒是随机选择的，DES 将会更容易受到攻击。这应该作为对所有想设计分组密码的人\\n一个警告：看上去随意的选择实际上完全不是随意的，如果做得不正确，则会使整个结构不\\n安全。'\n"
     ]
    }
   ],
   "source": [
    "print(f'{only_text=}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "bc6c961a-b688-483e-a5d7-a94c0da292d8",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "s='''\n",
    "DES 分组密码是一个拥有16轮的 Feistel 网络，且分块长度为64比特，密钥长度为56 比\\n特。回顾在Feistel 网络中，每一轮中使用的内部f函数一次只操作半个分块。因此，DES 轮\\n函数的输入/输出长度就是32比特。在DES的16轮中每轮所用到的轮函数都是由同一个变形\\n函数f:= $\\\\overline{{f}}$ 推导而来的。DES 的密码编排被用来从56 比特的主密钥k中获得每一轮的 48 比特\\n的子密钥k;。如在前一节所讨论的，第个轮函数/,就被定义为f(R）二 ${\\\\tilde{f}}(k_{i},$ R。正如从DES\\n使用 Feistel 结构这一事实所期望的，轮函数是不可逆的\\nDES的密钥编排相对比较简单，每一个子密钥k;都是由主密钥估算出的 48 比特的子集。\\n这里不精确地描述密钥编排。主密钥的 56 比特被分成两部分，即“左半部分”和“右半部\\n分”，其中每一部分含有 28比特（事实上，这种分离发生在密钥的初始置换之后，但是这里\\n的描述中忽略这些)。在每一轮中，子密钥最左边的 24比特被当作是主密钥左半部分 28 比特\\n的某个子集，而子密钥最右边的 24 比特被当作主密钥右半部分 28比特的某个子集。整个密\\n钥编排（包括比特被分为左半部分和右半部分，以及哪些比特被用来形成子密钥:;）都是确\\n定和公开的，唯一机密的是主密钥本身。\\nDES 变形函数了。前面曾经提到：变形函数了和第i个子密钥k:;共同决定了第轮函数f,\\nDES 中的变形函数是根据之前分析的范例构造出来的：它（本质上）只是一个单轮代替置换\\n网络。更详细地说，使用 $K_{i}\\\\in\\\\{0,1\\\\}$ 48和R∈ {0, 1}32计算了(k:;, R)，方法如下；首先R被扩展\\n成个 48比特的值R’。这是通过复制R一半的比特来完成的；用 $R^{\\\\prime}:=E(R)$ 来表示，这里瓦\\n代表扩展函数。然后，完全按照之前讨论的代替置换网络中的方法进行计算；展开值R’和k\\n进行异或运算，结果被分解为8块，每一块长度为6比特。每一个分块都经过（不同的）S\\n盒，S盒的输入为6比特且输出为4比特；把8个S盒的输出连接起来就得到了一个32比特\\n的结果。最后一步，对这个结果使用混合置换，从而获得 $\\\\hat{f}$ 的最终输出。构造过程图如图 5.4\\n所示。\\n与最初讨论的代替置换网络相比，这里的一个不同是上面所提到的S盒是不可逆的；实\\n际上，它们不可能是可逆的，因为它们的输入比输出长。更多关于S盒的结构细节在后面\\n给出。\\n再次强调上面所描述的一切（包括S盒本身以及混合置换）都是公开的。唯一保密的是\\n用来获得所有子密钥的主密钥。\\nS盒。构成广“核心”的8个S盒是 DES 构造方法中重要的组成部分，而且是精心设计\\n的（据报道是在国家安全局的帮助下)。对 DES 的研究表明；如果对S盒引入一些小变化\\n或者S盒是随机选择的，DES 将会更容易受到攻击。这应该作为对所有想设计分组密码的人\\n一个警告：看上去随意的选择实际上完全不是随意的，如果做得不正确，则会使整个结构不\\n安全。\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "29570106-8c8c-4a45-a963-673447506968",
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'DES 分组密码是一个拥有16轮的 Feistel 网络，且分块长度为64比特，密钥长度为56 比特。回顾在Feistel 网络中，每一轮中使用的内部f函数一次只操作半个分块。因此，DES 轮函数的输入/输出长度就是32比特。在DES的16轮中每轮所用到的轮函数都是由同一个变形函数f:= $\\\\overline{{f}}$ 推导而来的。DES 的密码编排被用来从56 比特的主密钥k中获得每一轮的 48 比特的子密钥k;。如在前一节所讨论的，第个轮函数/,就被定义为f(R）二 ${\\\\tilde{f}}(k_{i},$ R。正如从DES使用 Feistel 结构这一事实所期望的，轮函数是不可逆的DES的密钥编排相对比较简单，每一个子密钥k;都是由主密钥估算出的 48 比特的子集。这里不精确地描述密钥编排。主密钥的 56 比特被分成两部分，即“左半部分”和“右半部分”，其中每一部分含有 28比特（事实上，这种分离发生在密钥的初始置换之后，但是这里的描述中忽略这些)。在每一轮中，子密钥最左边的 24比特被当作是主密钥左半部分 28 比特的某个子集，而子密钥最右边的 24 比特被当作主密钥右半部分 28比特的某个子集。整个密钥编排（包括比特被分为左半部分和右半部分，以及哪些比特被用来形成子密钥:;）都是确定和公开的，唯一机密的是主密钥本身。DES 变形函数了。前面曾经提到：变形函数了和第i个子密钥k:;共同决定了第轮函数f,DES 中的变形函数是根据之前分析的范例构造出来的：它（本质上）只是一个单轮代替置换网络。更详细地说，使用 $K_{i}\\\\in\\\\{0,1\\\\}$ 48和R∈ {0, 1}32计算了(k:;, R)，方法如下；首先R被扩展成个 48比特的值R’。这是通过复制R一半的比特来完成的；用 $R^{\\\\prime}:=E(R)$ 来表示，这里瓦代表扩展函数。然后，完全按照之前讨论的代替置换网络中的方法进行计算；展开值R’和k进行异或运算，结果被分解为8块，每一块长度为6比特。每一个分块都经过（不同的）S盒，S盒的输入为6比特且输出为4比特；把8个S盒的输出连接起来就得到了一个32比特的结果。最后一步，对这个结果使用混合置换，从而获得 $\\\\hat{f}$ 的最终输出。构造过程图如图 5.4所示。与最初讨论的代替置换网络相比，这里的一个不同是上面所提到的S盒是不可逆的；实际上，它们不可能是可逆的，因为它们的输入比输出长。更多关于S盒的结构细节在后面给出。再次强调上面所描述的一切（包括S盒本身以及混合置换）都是公开的。唯一保密的是用来获得所有子密钥的主密钥。S盒。构成广“核心”的8个S盒是 DES 构造方法中重要的组成部分，而且是精心设计的（据报道是在国家安全局的帮助下)。对 DES 的研究表明；如果对S盒引入一些小变化或者S盒是随机选择的，DES 将会更容易受到攻击。这应该作为对所有想设计分组密码的人一个警告：看上去随意的选择实际上完全不是随意的，如果做得不正确，则会使整个结构不安全。'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s.replace('\\n','')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b2499db7-6ad9-447d-b10d-d8e3211a1074",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pix2text import Pix2Text\n",
    "\n",
    "img_fp = './pic/in1.png'\n",
    "p2t = Pix2Text(analyzer_config=dict(model_name='mfd'))\n",
    "outs = p2t(img_fp, resized_shape=600)  # 也可以使用 `p2t.recognize(img_fp)` 获得相同的结果\n",
    "print(outs)\n",
    "# 如果只需要识别出的文字和Latex表示，可以使用下面行的代码合并所有结果\n",
    "only_text = ''.join([out['text'] for out in outs])\n",
    "print(f'{only_text=}')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0554640-fd65-43b9-b567-22ddcb5cde12",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
